/*
*  SkyBufferManager.h
*  
*
*  Created by Alexander Trutchenko on 11/02/12.
*  Copyright 2012 Free Team. All rights reserved.
*
*/

#ifndef __Sky_BufferManager_h__
#define __Sky_BufferManager_h__

#include <string>
#include <map>
#include <vector>

namespace sky {

////////////////////////////////////////////////////////
//
/** SkyBufferManager
*  
*/
////////////////////////////////////////////////////////

class SkyStaticDecoder;
class SkyFileData;
class SkySoundFileData;
class SkyOpenALBuffer;
class SkyStreamDecoderFactory;
class SkyStreamDecoder;
class SkyStreamData;

class SkyBufferManager
{
friend class SkySoundEngine;

typedef std::vector<SkyStaticDecoder*> StaticDecoders; 
typedef std::map<std::string, SkyStreamDecoderFactory*> StreamDecodersFactories;

typedef std::map<std::string, SkySoundFileData*> CompressedFiles; 

typedef std::map<std::string, SkyOpenALBuffer*> StaticBuffers; 
typedef std::vector<SkyOpenALBuffer*> StreamBuffers; 

private:
	StaticDecoders _decoders;
	StreamDecodersFactories _decoderFactories;
	CompressedFiles _files;
	StaticBuffers _staticBuffers;
	StreamBuffers _streamBuffers;

	bool _isOutputDeviceOpened;
	bool _isCurrentContextSet;

private:
	SkyBufferManager();
	~SkyBufferManager();

public:
//Work with uncompressed files
		/* Preload compressed files */
	SkyFileData* preloadCompressedFile(const char* file);
		/* Unload compressed files */
	void unloadCompressedFile(const char* file);
		
//Work with stream buffers and decoders
		/* Create empty buffer */
	SkyOpenALBuffer* createStreamBuffer();
		/* Remove empty buffer */
	void removeStreamBuffer(SkyOpenALBuffer* buffer);
		/* Create stream decoder. Caller must delete it when it not needed */
	SkyStreamDecoder* decoderForFile(const char* file); // use file ext as a key
	SkyStreamDecoder* decoderForKey(const char* key, SkyStreamData* streamData); //only file ext or something else
		/* Add stream decoder factory */
	void addStreamDecoderFactoryForKey(SkyStreamDecoderFactory* factory, const char* key);

//Work with static buffers
	    /* Preload and uncompress(decode with decoders) file and move to OpenAL buffer */ 
	bool preloadFileToBuffer(const char* file);
		/* Free OpenAL buffer from the file */
	void unloadFileFromBuffer(const char* file);
		/* Returns buffer index for current file */
	SkyOpenALBuffer* bufferForFile(const char* file);

//Work with decoders
	void addStaticDecoder(SkyStaticDecoder* decoder);

private:
// Callbacks
	void onOpenOutputDevice();
	void onCloseOutputDevice();
	void onSetCurrentContext();
	void onClearCurrentContext();

		/* Clear buffers */
	void clearAllBuffers();

}; //class SkyBufferManager

} // namespace sky

#endif //__Sky_BufferManager_h__